package com.ywh.composetest.activity

import android.os.Bundle
import android.util.Log
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material3.Button
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableIntState
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableDoubleStateOf
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.neverEqualPolicy
import androidx.compose.runtime.referentialEqualityPolicy
import androidx.compose.runtime.remember
import androidx.compose.runtime.structuralEqualityPolicy
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.ywh.composetest.widget.SpacerHorizontal

class RefreshTestActivity : BaseComposeActivity() {
    @Composable
    override fun OnComposable(savedInstanceState: Bundle?) {
        val type = TYPE_ONE_PRO_ONE_STATE

        val basicTypeState = remember {
            mutableStateOf(true)
        }
        Column {
            SelectHeaderCompose(basicTypeState)
            if (!basicTypeState.value) {

            }
            when (type) {
                TYPE_ONE_PRO_ONE_STATE -> RefreshOneProOneStateCompose()
                TYPE_ONE_OBJECT -> RefreshOneObjectCompose()
                TYPE_ONE_OBJECT_2 -> RefreshOneObjectCompose2()
            }
        }

    }


    companion object {
        const val TYPE_ONE_PRO_ONE_STATE = "一个属性一个state"
        const val TYPE_ONE_OBJECT = "一个对象封装多个属性"
        const val TYPE_ONE_OBJECT_2 = "一个对象封装多个属性2"
    }
}

@Composable
private fun SelectHeaderCompose(basicTypeState: MutableState<Boolean>) {
    Column(modifier = Modifier.padding(horizontal = 12.dp)) {
        Text(text = "方式", fontSize = 14.sp)
        Row(verticalAlignment = Alignment.CenterVertically) {
            Text(text = "基本数据类型", fontSize = 14.sp)
            RadioButton(
                selected = basicTypeState.value,
                onClick = { basicTypeState.value = true }
            )
            SpacerHorizontal(width = 10.dp)
            Text(text = "对象", fontSize = 14.sp)
            RadioButton(
                selected = !basicTypeState.value,
                onClick = { basicTypeState.value = false }
            )
        }
    }
}

@Composable
fun RefreshOneProOneStateCompose() {
    val genderState = remember {
        mutableStateOf(1, structuralEqualityPolicy())
        mutableFloatStateOf()
        mutableDoubleStateOf()
        mutableLongStateOf()
        mutableStateListOf()
    }

    val nameState = remember {
        mutableStateOf("", referentialEqualityPolicy())
    }
    val phoneState = remember {
        mutableStateOf("")
    }
    Log.e("RefreshTest", "RefreshOneObjectCompose:name:${nameState.value}")
    Column {
        CommonGenderCompose("性别", genderState)

        CommonEditCompose("姓名", nameState.value) {
            nameState.value = it
        }

        CommonEditCompose("电话", phoneState.value) {
            phoneState.value = it
        }

        Button(onClick = {
            Log.e(
                "RefreshTest",
                "name:${nameState.value},phone:${phoneState.value}"
            )
        }) {
            Text(text = "点我")
        }
    }
}

@Composable
fun CommonGenderCompose(title: String, genderState: MutableState<Int>) {
    Log.e("RefreshTest", "title:${title},${genderState.value}")
    Column(modifier = Modifier.padding(horizontal = 12.dp)) {
        Text(text = title, fontSize = 14.sp)
        Row(verticalAlignment = Alignment.CenterVertically) {
            Text(text = "男", fontSize = 14.sp)
            RadioButton(
                selected = genderState.value == 1,
                onClick = { genderState.value = 1 }
            )
            SpacerHorizontal(width = 10.dp)
            Text(text = "女", fontSize = 14.sp)
            RadioButton(
                selected = genderState.value == 0,
                onClick = { genderState.value = 0 }
            )
        }
    }

}

@Composable
private fun CommonEditCompose(
    title: String,
    value: String,
    onValueChanged: (String) -> Unit
) {

    Log.e("RefreshTest", "title:${title},${value}")
    Column(modifier = Modifier.padding(horizontal = 12.dp)) {
        Text(text = title, fontSize = 14.sp)
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentHeight()
        ) {
            BasicTextField(
                value = value,
                modifier = Modifier.fillMaxWidth(),
                onValueChange = {
                    onValueChanged.invoke(it)
                },
                decorationBox = {
                    if (value.isEmpty()) {
                        Text(text = "请输入${title}", fontSize = 12.sp)
                    }
                    it.invoke()
                },
                minLines = 2,
                maxLines = 5
            )
        }
    }
}

data class User(
    val id: Int = 0,
    var name: String = "",
    var phone: String = ""
)

//copy  正常局部刷新； update:无法刷新，输入的值不写入
@Composable
fun RefreshOneObjectCompose() {
    val user = remember {
        mutableStateOf(User(), structuralEqualityPolicy())
    }

    val copy = false
    Log.e("RefreshTest", "RefreshOneObjectCompose:userState:${user}")
    Log.e(
        "RefreshTest",
        "RefreshOneObjectCompose:user:${user.value},hashCode:${user.value.hashCode()}"
    )
    Column {
        CommonEditCompose("姓名", user.value.name) {
            if (copy) {
//                user.value = user.value.copy(name = it)
            } else {
                user.update {
                    name = it
                }
            }
        }

        CommonEditCompose("电话", user.value.phone) {
            if (copy) {
//                user.value = user.value.copy(phone = it)
            } else {
                user.update {
                    phone = it
                }
            }
        }

        Button(onClick = {
            Log.e("RefreshTest", "Button:userState:${user}")
            Log.e("RefreshTest", "Button:user:${user.value},hashCode:${user.value.hashCode()}")
        }) {
            Text(text = "点我")
        }
    }
}

@Composable
fun RefreshOneObjectCompose2() {
    val user = remember {
        mutableStateOf(User(), neverEqualPolicy())
    }

    val copy = false
    Log.e("RefreshTest", "RefreshOneObjectCompose:userState:${user}")
    Log.e(
        "RefreshTest",
        "RefreshOneObjectCompose:user:${user.value},hashCode:${user.value.hashCode()}"
    )
    Column {
        CommonEditCompose("姓名", user.value.name) {
            if (copy) {
                user.value = user.value.copy(name = it)
            } else {
                user.update {
                    name = it
                }
            }
        }

        CommonEditCompose("电话", user.value.phone) {
            if (copy) {
                user.value = user.value.copy(phone = it)
            } else {
                user.update {
                    phone = it
                }
            }
        }

        Button(onClick = {
            Log.e("RefreshTest", "Button:userState:${user}")
            Log.e("RefreshTest", "Button:user:${user.value},hashCode:${user.value.hashCode()}")
        }) {
            Text(text = "点我")
        }
    }
}


fun <T> MutableState<T>.update(action: T.() -> Unit) {
    val value = value ?: return
    action.invoke(value)
    this.value = value
}

@Preview(showBackground = true)
@Composable
fun PreviewRefreshCompose() {
    RefreshOneProOneStateCompose()
}